package jblip.gui.components.view;

import java.awt.Desktop;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JEditorPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.HyperlinkEvent.EventType;

import jblip.gui.JBlip;
import jblip.gui.data.channels.TagDataChannel;
import jblip.gui.data.channels.UserDataChannel;
import jblip.resources.Update;

public class TextViewPane extends JEditorPane {
	
  private static final long serialVersionUID = 1L;

  private static final String UPDATE_REGEX =
      "^http://(?:www\\.)?blip\\.pl/(?:s|statuses|dm|directed_messages|pm|private_messages)/(\\d+)$";

  private static final String UPDATE_FORMAT =
      "<a href=\"@$1\" title=\"Blip $1\" alt=\"Blip #$1\">[blip]</a>";

  private static final String HTTP_REGEX =
      "^(https?://(?:[-\\w\\.]+)+(?::\\d+)?(?:/(?:[\\w/_\\.]*(?:\\?\\S+)?)?)?)";

  private static final String HTTP_FORMAT =
      "<a href=\"$1\" alt=\"$1\">[link]</a>";

  /*
   * private static final char[] PL_CHARS = new char[] { // polish unicode chars
   * followed by latinified versions 0xD3, 'O', 0xF3, 'o', 0x104, 'A', 0x105,
   * 'a', 0x118, 'E', 0x119, 'e', 0x106, 'C', 0x107, 'c', 0x141, 'l', 0x142,
   * 'L', 0x143, 'N', 0x144, 'n', 0x15A, 'S', 0x15B, 's', 0x179, 'Z', 0x17A,
   * 'z', 0x17B, 'Z', 0x17C, 'z' };
   */

  private static final String PL_REGEX =
      "\\u00D3\\u00F3\\u0104\\u0105\\u0118\\u0119\\u0106\\u0107\\u0141\\u0142\\u0143\\u0144\\u015A\\u015B\\u0179\\u017A\\u017B\\u017C";

  private static final String TAG_REGEX = "(#[-\\w" + PL_REGEX + "]{3,})";

  private static final String TAG_FORMAT =
      "<a href=\"$1\" alt=\"Tag $1\">$1</a>";

  private static final String USER_REGEX = "(\\^\\w{3,})";

  private static final String USER_FORMAT =
      "<a href=\"$1\" alt=\"Użytkownik $1\">$1</a>";

  protected static String tagify(final String raw) {
    final StringBuilder sb = new StringBuilder(255);
    final StringBuilder word = new StringBuilder(31);
    for (char next : raw.toCharArray()) {
      if (Character.isWhitespace(next)) {
        sb.append(tagifyWord(word));
        word.delete(0, word.length());
        sb.append(next);
      } else {
        word.append(next);
      }
    }
    sb.append(tagifyWord(word));
    return sb.toString();
  }

  protected static String tagifyWord(final StringBuilder word) {
    if (word.length() == 0) {
      return "";
    }

    final Matcher mat_update = Pattern.compile(UPDATE_REGEX).matcher(word);
    final Matcher mat_http = Pattern.compile(HTTP_REGEX).matcher(word);
    final Matcher mat_tag = Pattern.compile(TAG_REGEX).matcher(word);
    final Matcher mat_user = Pattern.compile(USER_REGEX).matcher(word);

    if (mat_update.find()) {
      return mat_update.replaceAll(UPDATE_FORMAT);
    } else if (mat_http.find()) {
      return mat_http.replaceAll(HTTP_FORMAT);
    } else if (mat_tag.find()) {
      return mat_tag.replaceAll(TAG_FORMAT);
    } else if (mat_user.find()) {
      return mat_user.replaceAll(USER_FORMAT);
    } else {
      return word.toString();
    }

  }

  public TextViewPane(final String text) {
    super("text/html", tagify(text));
    setEditable(false);
    setOpaque(false);
    addHyperlinkListener(new TextViewPaneHyperlinkListener(this));
  }
}
